---
title: TypeScript
description:
  Learn how to use Anchor's TypeScript client library to interact with Solana
  programs
---

Anchor provides a Typescript client library
([@coral-xyz/anchor](https://github.com/coral-xyz/anchor/tree/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor))
that simplifies the process of interacting with Solana programs from the client
in JavaScript or TypeScript.

<Callout type="info">
  The `@coral-xyz/anchor` library is only compatible with the legacy version
  (v1) of `@solana/web3.js` and `@solana/spl-token`. It is not compatible with
  the new version (v2) of `@solana/web3.js`.
</Callout>

## Client Program

To interact with an Anchor program using `@coral-xyz/anchor`, you'll need to
create a
[`Program`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/index.ts#L58)
instance using the program's [IDL file](/docs/basics/idl).

Creating an instance of the `Program` requires the program's IDL and an
[`AnchorProvider`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/provider.ts#L59).
An `AnchorProvider` is an abstraction that combines two things:

- `Connection` - the connection to a Solana cluster (i.e. localhost, devnet,
  mainnet)
- `Wallet` - (optional) a default wallet used to pay for and sign transactions

<Tabs items={['Frontend/Node', 'Test File']}>
<Tab value="Frontend/Node">

When integrating with a frontend using the
[Solana wallet adapter](https://github.com/anza-xyz/wallet-adapter), you'll need
to set up the `AnchorProvider` and `Program`.

```ts title="example"
import { Program, AnchorProvider, setProvider } from "@coral-xyz/anchor";
import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";
import type { HelloAnchor } from "./idlType";
import idl from "./idl.json";

const { connection } = useConnection();
const wallet = useAnchorWallet();

// [!code word:AnchorProvider]
// [!code highlight:2]
const provider = new AnchorProvider(connection, wallet, {});
setProvider(provider);

// [!code word:Program]
// [!code highlight:3]
export const program = new Program(idl as HelloAnchor, {
  connection,
});
```

In the code snippet above:

- `idl.json` is the IDL file generated by Anchor, found at
  `/target/idl/<program-name>.json` in an Anchor project.
- `idlType.ts` is the IDL type (for use with TypeScript), found at
  `/target/types/<program-name>.ts` in an Anchor project.

Alternatively, you can create an `Program` instance using only the IDL and the
`Connection` to a Solana cluster. This means there is no default `Wallet`, but
allows you to use the `Program` to fetch accounts or build instructions without
a connected wallet.

```ts
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
import { Program } from "@coral-xyz/anchor";
import type { HelloAnchor } from "./idlType";
import idl from "./idl.json";

const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// [!code word:Program]
// [!code highlight:3]
export const program = new Program(idl as HelloAnchor, {
  connection,
});
```

</Tab>
<Tab value="Test File">

When creating a new Anchor project, a default test file is generated that
includes a `Program` instance. This setup differs from applications outside the
Anchor workspace (like React or Node.js) where you'll need to manually create
the `Program` instance.

```ts
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { HelloAnchor } from "../target/types/hello_anchor";

describe("hello_anchor", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  // [!code highlight]
  const program = anchor.workspace.HelloAnchor as Program<HelloAnchor>;

  it("Is initialized!", async () => {
    // Add your test here.
    const tx = await program.methods.initialize().rpc();
    console.log("Your transaction signature", tx);
  });
});
```

</Tab>
</Tabs>

## Invoke Instructions

Once the `Program` is set up using a program's IDL file, you can use the Anchor
[`MethodsBuilder`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/methods.ts#L155)
to:

- Build individual instructions
- Build transactions
- Build and send transactions

The basic format looks like the following:

<Tabs items={['methods', 'instruction', 'accounts', `signers`]}>
<Tab value="methods">

`program.methods` - This is the builder API for creating instruction calls from
the program's IDL

```ts
// [!code word:methods]
// [!code highlight]
await program.methods
  .instructionName(instructionData)
  .accounts({})
  .signers([])
  .rpc();
```

</Tab>
<Tab value="instruction">

Following `.methods`, specify the name of an instruction from the program IDL,
passing in any required arguments as comma-separated values.

```ts
// [!code word:instructionName]
await program.methods
  // [!code highlight]
  .instructionName(instructionData1, instructionData2)
  .accounts({})
  .signers([])
  .rpc();
```

</Tab>
<Tab value="accounts">

`.accounts` - Pass in the address of the accounts required by the instruction as
specified in the IDL

```ts
// [!code word:accounts]
await program.methods
  .instructionName(instructionData)
  // [!code highlight]
  .accounts({})
  .signers([])
  .rpc();
```

Note that certain account addresses don't need to be explicitly provided, as
they can automatically resolve using information included in the IDL. These
typically include:

- Common accounts (ex. the System Program)
- Accounts where the address is a PDA (Program Derived Address)

</Tab>
<Tab value="signers">

`.signers` - Optionally pass in an array of keypairs required as additional
signers by the instruction. This is commonly used when creating new accounts
where the account address is the public key of a newly generated keypair.

```ts
// [!code word:signers]
await program.methods
  .instructionName(instructionData)
  .accounts({})
  // [!code highlight]
  .signers([])
  .rpc();
```

<Callout type="info">
  Note that `.signers` should only be used when also using `.rpc()`. When using
  `.transaction()` or `.instruction()`, signers should be added to the
  transaction before sending.
</Callout>

</Tab>
</Tabs>

Anchor provides multiple methods for building program instructions:

<Tabs items={['.rpc', '.transaction', '.instruction']}>
<Tab value=".rpc">

The
[`rpc()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/methods.ts#L428)
method
[sends a signed transaction](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/rpc.ts#L29)
with the specified instruction and returns a `TransactionSignature`.

When using `.rpc`, the `Wallet` from the `Provider` is automatically included as
a signer.

```ts
// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const transactionSignature = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .signers([newAccountKp])
  // [!code word:rpc]
  // [!code highlight]
  .rpc();
```

</Tab>
<Tab value=".transaction">

The
[`transaction()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/methods.ts#L348)
method
[builds a `Transaction`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/transaction.ts#L18-L26)
with the specified instruction without sending the transaction.

```ts
// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const transaction = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  // [!code word:transaction:1]
  // [!code highlight]
  .transaction();

const transactionSignature = await connection.sendTransaction(transaction, [
  wallet.payer,
  newAccountKp,
]);
```

</Tab>
<Tab value=".instruction">

The
[`instruction()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/methods.ts#L323)
method
[builds a `TransactionInstruction`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/instruction.ts#L57-L61)
using the specified instruction. This is useful if you want to manually add the
instruction to a transaction and combine it with other instructions.

```ts
// Generate keypair for the new account
const newAccountKp = new Keypair();

const data = new BN(42);
const instruction = await program.methods
  .initialize(data)
  .accounts({
    newAccount: newAccountKp.publicKey,
    signer: wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  // [!code word:instruction:1]
  // [!code highlight]
  .instruction();

const transaction = new Transaction().add(instruction);

const transactionSignature = await connection.sendTransaction(transaction, [
  wallet.payer,
  newAccountKp,
]);
```

</Tab> 
</Tabs>

## Fetch Accounts

The `Program` client simplifies the process of fetching and deserializing
accounts created by your Anchor program.

Use `program.account` followed by the name of the account type defined in the
IDL. Anchor provides multiple methods for fetching accounts.

<Tabs items={['all', 'memcmp', 'fetch', 'fetchMultiple']}>
<Tab value="all">

Use
[`all()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/account.ts#L251)
to fetch all existing accounts for a specific account type.

```ts
// [!code word:all]
const accounts = await program.account.newAccount.all();
```

</Tab>
<Tab value="memcmp">

Use `memcmp` (memory compare) to filter for account data that matches a specific
value at a specific offset. Using `memcmp` requires you to understand the byte
layout of the data field for the account type you are fetching.

When calculating the offset, remember that the first 8 bytes in accounts created
by an Anchor program are reserved for the account discriminator.

```ts
// [!code word:memcmp]
const accounts = await program.account.newAccount.all([
  {
    // [!code highlight:4]
    memcmp: {
      offset: 8,
      bytes: "",
    },
  },
]);
```

</Tab>
<Tab value="fetch">

Use
[`fetch()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/account.ts#L165)
to fetch the account data for a single account

```ts
// [!code word:fetch]
const account = await program.account.newAccount.fetch(ACCOUNT_ADDRESS);
```

</Tab>
<Tab value="fetchMultiple">

Use
[`fetchMultiple()`](https://github.com/coral-xyz/anchor/blob/0e5285aecdf410fa0779b7cd09a47f235882c156/ts/packages/anchor/src/program/namespace/account.ts#L200)
to fetch the account data for multiple accounts by passing in an array of
account addresses

```ts
// [!code word:fetchMultiple]
const accounts = await program.account.newAccount.fetchMultiple([
  ACCOUNT_ADDRESS_ONE,
  ACCOUNT_ADDRESS_TWO,
]);
```

</Tab>
</Tabs>

## Example

The example below demonstrates how to use `@coral-xyz/anchor` to interact with a
simple Anchor program. The program has two instructions:

- `initialize` – Creates and initializes a counter account to store a value
- `increment` – Increments the value stored on the counter account

```rust title="lib.rs"
use anchor_lang::prelude::*;

declare_id!("6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC");

#[program]
pub mod example {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &ctx.accounts.counter;
        msg!("Counter account created! Current count: {}", counter.count);
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        msg!("Previous counter: {}", counter.count);

        counter.count += 1;
        msg!("Counter incremented! Current count: {}", counter.count);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,

    #[account(
        init,
        payer = payer,
        space = 8 + 8
    )]
    pub counter: Account<'info, Counter>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub counter: Account<'info, Counter>,
}

#[account]
pub struct Counter {
    pub count: u64,
}
```

Below is an example folder structure for a TypeScript client that interacts with
the Anchor program:

<Files>
  <Folder name="ts" defaultOpen={true}>
    <Folder name="idl" defaultOpen={true}>
      <File name="example.json" />
      <File name="example.ts" />
    </Folder>
    <File name="example.ts" />
    <File name="package.json" />
  </Folder>
</Files>

The `/idl` directory in the example includes two files:

- `example.json`: The IDL file for the program
- `example.ts`: A TypeScript type definition file generated for the IDL

The tabs below include the `example.json` and `example.ts` files as a reference
of what these files look like.

<Tabs items={["example.json", "example.ts"]}>

```json tab="example.json"
{
  "address": "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC",
  "metadata": {
    "name": "example",
    "version": "0.1.0",
    "spec": "0.1.0",
    "description": "Created with Anchor"
  },
  "instructions": [
    {
      "name": "increment",
      "discriminator": [11, 18, 104, 9, 104, 174, 59, 33],
      "accounts": [
        {
          "name": "counter",
          "writable": true
        }
      ],
      "args": []
    },
    {
      "name": "initialize",
      "discriminator": [175, 175, 109, 31, 13, 152, 155, 237],
      "accounts": [
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "counter",
          "writable": true,
          "signer": true
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": []
    }
  ],
  "accounts": [
    {
      "name": "Counter",
      "discriminator": [255, 176, 4, 245, 188, 253, 124, 25]
    }
  ],
  "types": [
    {
      "name": "Counter",
      "type": {
        "kind": "struct",
        "fields": [
          {
            "name": "count",
            "type": "u64"
          }
        ]
      }
    }
  ]
}
```

```ts tab="example.ts"
/**
 * Program IDL in camelCase format in order to be used in JS/TS.
 *
 * Note that this is only a type helper and is not the actual IDL. The original
 * IDL can be found at `target/idl/example.json`.
 */
export type Example = {
  address: "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC";
  metadata: {
    name: "example";
    version: "0.1.0";
    spec: "0.1.0";
    description: "Created with Anchor";
  };
  instructions: [
    {
      name: "increment";
      discriminator: [11, 18, 104, 9, 104, 174, 59, 33];
      accounts: [
        {
          name: "counter";
          writable: true;
        },
      ];
      args: [];
    },
    {
      name: "initialize";
      discriminator: [175, 175, 109, 31, 13, 152, 155, 237];
      accounts: [
        {
          name: "payer";
          writable: true;
          signer: true;
        },
        {
          name: "counter";
          writable: true;
          signer: true;
        },
        {
          name: "systemProgram";
          address: "11111111111111111111111111111111";
        },
      ];
      args: [];
    },
  ];
  accounts: [
    {
      name: "counter";
      discriminator: [255, 176, 4, 245, 188, 253, 124, 25];
    },
  ];
  types: [
    {
      name: "counter";
      type: {
        kind: "struct";
        fields: [
          {
            name: "count";
            type: "u64";
          },
        ];
      };
    },
  ];
};
```

</Tabs>

<Callout type="info">

When you run `anchor build` in an Anchor project, the Anchor CLI automatically
generates:

- The IDL file (`.json`) in the `target/idl` folder (ex.
  `target/idl/example.json`)

- The TypeScript type definitions (`.ts`) in the `target/types` folder (ex.
  `target/types/example.ts`)

</Callout>

The `example.ts` file below includes the script to interact with the program.

```ts title="example.ts"
import {
  Connection,
  Keypair,
  LAMPORTS_PER_SOL,
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import { Program } from "@coral-xyz/anchor";
import type { Example } from "./idl/example.ts";
import idl from "./idl/example.json";

// Set up a connection to the cluster
const connection = new Connection("http://127.0.0.1:8899", "confirmed");

// Create a Program instance using the IDL and connection
const program = new Program(idl as Example, {
  connection,
});

// Generate new Keypairs for the payer and the counter account
const payer = Keypair.generate();
const counter = Keypair.generate();

// Airdrop SOL to fund the payer's account for transaction fees
const airdropTransactionSignature = await connection.requestAirdrop(
  payer.publicKey,
  LAMPORTS_PER_SOL,
);
await connection.confirmTransaction(airdropTransactionSignature);

// Build the initialize instruction
const initializeInstruction = await program.methods
  .initialize()
  .accounts({
    payer: payer.publicKey,
    counter: counter.publicKey,
  })
  .instruction();

// Build the increment instruction
const incrementInstruction = await program.methods
  .increment()
  .accounts({
    counter: counter.publicKey,
  })
  .instruction();

// Add both instructions to a single transaction
const transaction = new Transaction().add(
  initializeInstruction,
  incrementInstruction,
);

// Send the transaction
const transactionSignature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, counter],
);
console.log("Transaction Signature", transactionSignature);

// Fetch the counter account
const counterAccount = await program.account.counter.fetch(counter.publicKey);
console.log("Count:", counterAccount.count);
```
